//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V0.2.0
#include "i2c_bsp.h"
#include "stm32f10x.h"
#include "stm32f10x_i2c.h"
#include "misc.h"
#include <stdlib.h>
#include <string.h>

/*I2C主模式下的状态码枚举*/
typedef enum
{
    I2C_Master_Start = 0,      //启动信号
    I2C_Master_Restart,        //重复启动信号
    I2C_Master_Write_Addr,     //写地址有应答
    I2C_Master_Read_Addr,      //读地址有应答
    I2C_Master_Send_Cmd,       //写命令有应答
    I2C_Master_Send_Data,      //写数据有应答
    I2C_Master_Receive_Data,   //读数据
    I2C_Master_DMA_Send_End,   //DMA发送结束
    I2C_Master_DMA_Receive_End,//DMA接收结束
}WHT_I2C_Master_State_Code_enum;

typedef struct
{
    void (*GPIO_Init_CB)(void);//引脚必须开漏模式
}WHT_I2C_GPIO_t;

/*软I2C总线结构体*/
typedef struct
{
    WHT_I2C_BUS_t Info;          //总线信息
    unsigned int Delay_Count;    //延迟时间
    I2C_TypeDef* I2C_BUS;        //总线外设
    WHT_I2C_GPIO_t GPIO;         //总线GPIO
    WHT_I2C_Cache_t* Cache;      //外设缓存,由外部设备提供
    WHT_I2C_Master_State_Code_enum Master_State_Code;//状态机形式
    WHT_DMA_Config_t DMA_Send_Config;   //DMA发送配置
    WHT_DMA_Config_t DMA_Receive_Config;//DMA接收配置
}WHT_I2C_BUS_Private_t;

#ifndef NULL
#define NULL           ((void*)0)
#endif
#define WHT_BUS        ((WHT_I2C_BUS_Private_t*)bus)

static WHT_I2C_BUS_Private_t* WHT_I2C_BUS[2];//I2C总线2个


/*I2C状态码检查*/
static void WHT_I2C_BSP_Check_Error_Code(WHT_I2C_BUS_t* bus)
{
    unsigned int error_code;

    error_code = I2C_ReadRegister(WHT_BUS->I2C_BUS, I2C_Register_SR1);
    error_code &= I2C_FLAG_AF|I2C_FLAG_BERR|I2C_FLAG_TIMEOUT|I2C_FLAG_PECERR|I2C_FLAG_OVR|I2C_FLAG_ARLO;
    if (error_code != RESET)
    {
        if (error_code & I2C_FLAG_AF)
        {
            I2C_ClearFlag(WHT_BUS->I2C_BUS, I2C_FLAG_AF);
			*(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_Slave_No_ACK;
        }
        else if (error_code & I2C_FLAG_BERR)
        {
            I2C_ClearFlag(WHT_BUS->I2C_BUS, I2C_FLAG_BERR);
            *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_BUS_Error;
        }
        else if (error_code & I2C_FLAG_TIMEOUT)
        {
            I2C_ClearFlag(WHT_BUS->I2C_BUS, I2C_FLAG_TIMEOUT);
            *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_Tx_Send_Error;
        }
        else if (error_code & I2C_FLAG_PECERR)
        {
            I2C_ClearFlag(WHT_BUS->I2C_BUS, I2C_FLAG_PECERR);
            *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_Other_Error;
        }
        else if (error_code & I2C_FLAG_OVR)
        {
            I2C_ClearFlag(WHT_BUS->I2C_BUS, I2C_FLAG_OVR);
            *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_Rx_Over_Error;
        }
        else if (error_code & I2C_FLAG_ARLO)
        {
            I2C_ClearFlag(WHT_BUS->I2C_BUS, I2C_FLAG_ARLO);
            *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_ARLO_Error;
        }
    }
}
/*I2C发送起始信号*/
static void WHT_I2C_BSP_Send_Start(WHT_I2C_BUS_t* bus)
{
    I2C_Cmd(WHT_BUS->I2C_BUS, ENABLE);          //使能i2c
    I2C_GenerateSTART(WHT_BUS->I2C_BUS, ENABLE);//Send i2c Start
}
/*I2C发送从设备地址并写操作*/
static void WHT_I2C_BSP_Send_Slave_Addr_Write(WHT_I2C_BUS_t* bus)
{
    do
    {
        if (I2C_CheckEvent(WHT_BUS->I2C_BUS, I2C_EVENT_MASTER_MODE_SELECT) == SUCCESS)//EV5 i2c start
        {
            I2C_Send7bitAddress(WHT_BUS->I2C_BUS, WHT_BUS->Cache->Addr_7Bit << 1, I2C_Write);
            break;
        }
        WHT_I2C_BSP_Check_Error_Code(bus);
        if (WHT_BUS->Info.State != I2C_No_Error)
            break;
    } while (1);
}
/*I2C发送从设备地址并读操作*/
static void WHT_I2C_BSP_Send_Slave_Addr_Read(WHT_I2C_BUS_t* bus)
{
    do
    {
        if (I2C_CheckEvent(WHT_BUS->I2C_BUS, I2C_EVENT_MASTER_MODE_SELECT) == SUCCESS)//EV5 i2c start
        {
            I2C_Send7bitAddress(WHT_BUS->I2C_BUS, WHT_BUS->Cache->Addr_7Bit << 1, I2C_Read);
            break;
        }
        WHT_I2C_BSP_Check_Error_Code(bus);
        if (WHT_BUS->Info.State != I2C_No_Error)
            break;
    } while (1);
}
/*I2C发送从设备命令*/
static void WHT_I2C_BSP_Send_Slave_Cmd(WHT_I2C_BUS_t* bus)
{
    do
    {
        if (I2C_CheckEvent(WHT_BUS->I2C_BUS, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == SUCCESS)//EV6 send addr have ack
            break;
        WHT_I2C_BSP_Check_Error_Code(bus);
        if (WHT_BUS->Info.State != I2C_No_Error)
            return;
    } while (1);

    for (char i = 0; i < WHT_BUS->Cache->Cmd_Count; i++)
    {
        I2C_SendData(WHT_BUS->I2C_BUS, WHT_BUS->Cache->Cmd[i]);
        do
        {
            if (I2C_CheckEvent(WHT_BUS->I2C_BUS, I2C_EVENT_MASTER_BYTE_TRANSMITTED) == SUCCESS)//EV8_2 send data have ack
                break;
            WHT_I2C_BSP_Check_Error_Code(bus);
            if (WHT_BUS->Info.State != I2C_No_Error)
                return;
        } while (1);
    }
}
/*I2C发送数据*/
static void WHT_I2C_BSP_Send_Data(WHT_I2C_BUS_t* bus)
{
    for (unsigned int i = 0; i < WHT_BUS->Cache->Buffer_Count; i++)
    {
        I2C_SendData(WHT_BUS->I2C_BUS, WHT_BUS->Cache->Buffer[i]);
        do
        {
            if (I2C_CheckEvent(WHT_BUS->I2C_BUS, I2C_EVENT_MASTER_BYTE_TRANSMITTED) == SUCCESS)//EV8_2 send data have ack
                break;
            WHT_I2C_BSP_Check_Error_Code(bus);
            if (WHT_BUS->Info.State != I2C_No_Error)
                return;
        } while (1);
    }
}
/*I2C读取数据*/
static void WHT_I2C_BSP_Receive_Data(WHT_I2C_BUS_t* bus)
{
    if (WHT_BUS->Cache->Buffer_Count == 0)
    {
        I2C_GenerateSTOP(WHT_BUS->I2C_BUS, ENABLE);//Last Data Send
        return;
    }
    WHT_I2C_BSP_Send_Start(bus);//Send i2c restart
    WHT_I2C_BSP_Send_Slave_Addr_Read(bus);//send read slave
    if (WHT_BUS->Info.State != I2C_No_Error)
    {
        I2C_GenerateSTOP(WHT_BUS->I2C_BUS, ENABLE);//Last Data Send
        return;
    }
    do
    {
        if (I2C_CheckEvent(WHT_BUS->I2C_BUS, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) == SUCCESS)//EV6 read addr have ack
            break;
        WHT_I2C_BSP_Check_Error_Code(bus);
        if (WHT_BUS->Info.State != I2C_No_Error)
        {
            I2C_GenerateSTOP(WHT_BUS->I2C_BUS, ENABLE);//Last Data Send
            return;
        }
    } while (1);
    if (WHT_BUS->Cache->Buffer_Count == 1)
    {
        I2C_GenerateSTOP(WHT_BUS->I2C_BUS, ENABLE);
        do
        {
            if (I2C_CheckEvent(WHT_BUS->I2C_BUS, I2C_EVENT_MASTER_BYTE_RECEIVED) == SUCCESS)//EV7 receive data
            {
                WHT_BUS->Cache->Buffer[0] = I2C_ReceiveData(WHT_BUS->I2C_BUS);
                break;
            }
        } while (1);
    }
    else
    {
        I2C_AcknowledgeConfig(WHT_BUS->I2C_BUS, ENABLE);
        for (unsigned int i = 0; i < WHT_BUS->Cache->Buffer_Count; i++)
        {
            do
            {
                if (I2C_CheckEvent(WHT_BUS->I2C_BUS, I2C_EVENT_MASTER_BYTE_RECEIVED) == SUCCESS)//EV7 receive data
                {
                    WHT_BUS->Cache->Buffer[i] = I2C_ReceiveData(WHT_BUS->I2C_BUS);
                    if ((i+2) == WHT_BUS->Cache->Buffer_Count)
                    {
                        I2C_AcknowledgeConfig(WHT_BUS->I2C_BUS, DISABLE);
                        I2C_GenerateSTOP(WHT_BUS->I2C_BUS, ENABLE);
                    }
                    break;
                }
            } while (1);
        }
    }
}


/*I2C回调用户的中断函数*/
static void WHT_I2C_BSP_User_IT_Callback(WHT_I2C_BUS_Private_t* BUS)
{
    *(WHT_I2C_BUS_Lock_enum*)&BUS->Info.Mutex = I2C_Unlock;
    if (BUS->Cache->Dir == I2C_Write)
    {
        if (BUS->Cache->Write_Finish_IT_CB != NULL)
            BUS->Cache->Write_Finish_IT_CB();
    }
    else
    {
        if (BUS->Cache->Read_Finish_IT_CB != NULL)
            BUS->Cache->Read_Finish_IT_CB();
    }
}
/*I2C DMA发送和接收回调函数*/
static void WHT_I2C_BSP_DMA_Send_Receive_Callback(WHT_I2C_BUS_Private_t* BUS)
{
    if (BUS->Master_State_Code == I2C_Master_DMA_Receive_End)//DMA Receive End
    {
        I2C_GenerateSTOP(BUS->I2C_BUS, ENABLE);      //Send Stop
        I2C_DMACmd(BUS->I2C_BUS, DISABLE);           //OFF DMA请求
        I2C_ITConfig(BUS->I2C_BUS, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, DISABLE);//Off All Interrupt
        I2C_AcknowledgeConfig(BUS->I2C_BUS, DISABLE);//OFF ACK
        I2C_Cmd(BUS->I2C_BUS, DISABLE);              //OFF I2C
        BUS->Master_State_Code = I2C_Master_Start;   //Reset I2C State
        WHT_I2C_BSP_User_IT_Callback(BUS);
    }
    else
    {
        if (BUS->DMA_Send_Config.Info->State == TRx_TC)
        {
            I2C_DMACmd(BUS->I2C_BUS, DISABLE);             //OFF DMA请求
            I2C_ITConfig(BUS->I2C_BUS, I2C_IT_EVT, ENABLE);//ON IT_Event
        }
        else
        {
            I2C_GenerateSTOP(BUS->I2C_BUS, ENABLE);        //Send Stop
            I2C_DMACmd(BUS->I2C_BUS, DISABLE);             //OFF DMA请求
            I2C_ITConfig(BUS->I2C_BUS, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, DISABLE);//Off All Interrupt
            I2C_Cmd(BUS->I2C_BUS, DISABLE);                //OFF I2C
            BUS->Master_State_Code = I2C_Master_Start;     //Reset I2C State
            *(WHT_I2C_BUS_State_enum*)&BUS->Info.State = I2C_Other_Error;//I2C Idle
            WHT_I2C_BSP_User_IT_Callback(BUS);
        }
    }
}
static void WHT_I2C1_BSP_DMA_Send_Receive_Callback(void)
{
    WHT_I2C_BSP_DMA_Send_Receive_Callback(WHT_I2C_BUS[0]);
}
static void WHT_I2C2_BSP_DMA_Send_Receive_Callback(void)
{
    WHT_I2C_BSP_DMA_Send_Receive_Callback(WHT_I2C_BUS[1]);
}


/*I2C阻塞读写*/
static void WHT_I2C_BUS_Read_Write(WHT_I2C_BUS_t* bus, WHT_I2C_Cache_t* cache)
{
    unsigned int wait_i2c_stop_send_over;/*当发送stop后关闭i2c则不会立即关闭i2c的此时在向外发送stop信号*/

    *(WHT_I2C_BUS_Lock_enum*)&WHT_BUS->Info.Mutex = I2C_Lock;
    *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_No_Error;
    WHT_BUS->Cache = cache;

    //检测总线状态
    wait_i2c_stop_send_over = WHT_BUS->Delay_Count;
    while (I2C_GetFlagStatus(WHT_BUS->I2C_BUS, I2C_FLAG_BUSY) == SET)
    {
        if (wait_i2c_stop_send_over-- == 0)
        {
            *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_BUS_Error;
            *(WHT_I2C_BUS_Lock_enum*)&WHT_BUS->Info.Mutex = I2C_Unlock;
            return;
        }
    }
    
    I2C_ITConfig(WHT_BUS->I2C_BUS, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, DISABLE);

    WHT_I2C_BSP_Send_Start(bus);           //发送开始信号
    WHT_I2C_BSP_Send_Slave_Addr_Write(bus);//发送设备地址
    if (WHT_BUS->Info.State != I2C_No_Error)
        goto Send_Over;
    WHT_I2C_BSP_Send_Slave_Cmd(bus);       //发送命令
    if (WHT_BUS->Info.State != I2C_No_Error)
        goto Send_Over;
    
    if (WHT_BUS->Cache->Dir == I2C_Write)    //发送数据
    {
        WHT_I2C_BSP_Send_Data(bus);
    }
    else                 //接收数据
    {
        WHT_I2C_BSP_Receive_Data(bus);
        goto Receive_Over;
    }
Send_Over:
    I2C_GenerateSTOP(WHT_BUS->I2C_BUS, ENABLE);//send stop
Receive_Over:
    I2C_Cmd(WHT_BUS->I2C_BUS, DISABLE);        //关闭i2c
    *(WHT_I2C_BUS_Lock_enum*)&WHT_BUS->Info.Mutex = I2C_Unlock;
}
/*I2C中断读写*/
static void WHT_I2C_BUS_Read_Write_IT(WHT_I2C_BUS_t* bus, WHT_I2C_Cache_t* cache)
{
    unsigned int wait_i2c_stop_send_over;/*当发送stop后关闭i2c则不会立即关闭i2c的此时在向外发送stop信号*/

    *(WHT_I2C_BUS_Lock_enum*)&WHT_BUS->Info.Mutex = I2C_Lock;
    *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_No_Error;
    WHT_BUS->Cache = cache;

    if (WHT_BUS->Cache->Cmd_Count < 1)
    {
        *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_Other_Error;
        *(WHT_I2C_BUS_Lock_enum*)&WHT_BUS->Info.Mutex = I2C_Unlock;
        return;
    }
	
    //默认此设备的I2C工作在从模式,跳出从模式只需要发送I2C起始信号即可
    //检测总线状态  
    wait_i2c_stop_send_over = WHT_BUS->Delay_Count;
    while (I2C_GetFlagStatus(WHT_BUS->I2C_BUS, I2C_FLAG_BUSY) == SET)
    {
        if (wait_i2c_stop_send_over-- == 0)
        {
            *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_BUS_Error;
            *(WHT_I2C_BUS_Lock_enum*)&WHT_BUS->Info.Mutex = I2C_Unlock;
            return;
        }
    }

    WHT_BUS->Master_State_Code = I2C_Master_Start;
    I2C_ITConfig(WHT_BUS->I2C_BUS, I2C_IT_EVT | I2C_IT_ERR, ENABLE);//IT Enable   I2C_IT_BUF
    WHT_I2C_BSP_Send_Start(bus);
}
/*I2C DMA读写*/
static void WHT_I2C_BUS_Read_Write_DMA(WHT_I2C_BUS_t* bus, WHT_I2C_Cache_t* cache)
{
    unsigned int wait_i2c_stop_send_over;/*当发送stop后关闭i2c则不会立即关闭i2c的此时在向外发送stop信号*/
    DMA_InitTypeDef DMA_InitStruct =
    {
        //.DMA_PeripheralBaseAddr = (unsigned int)&I2C1->DR,    //外设基地址
        //.DMA_MemoryBaseAddr     = RESET,                      //默认值
        //.DMA_DIR                = DMA_DIR_PeripheralDST,      //M->P
        //.DMA_BufferSize         = 0,                          //默认值
        .DMA_PeripheralInc      = DMA_PeripheralInc_Disable,  //外设地址不递增
        .DMA_MemoryInc          = DMA_MemoryInc_Enable,       //存储器地址递增
        .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,//外设数据大小为字节
        .DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte,    //存储器数据大小为字节，跟外设数据大小相同
        .DMA_Mode               = DMA_Mode_Normal,            //单次传输模式
        .DMA_Priority           = DMA_Priority_Low,           //优先级最低
        .DMA_M2M                = DMA_M2M_Disable,            //禁止存储器到存储器模式，因为是从存储器到外设
    };

    *(WHT_I2C_BUS_Lock_enum*)&WHT_BUS->Info.Mutex = I2C_Lock;
    *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_No_Error;
    WHT_BUS->Cache = cache;
    
    if ((WHT_BUS->Cache->Dir == I2C_Write) && (WHT_BUS->Cache->Buffer_Count == 0))
    {
        WHT_I2C_BUS_Read_Write(bus, cache);
        return;
    }
    else if ((WHT_BUS->Cache->Dir == I2C_Read) && (WHT_BUS->Cache->Buffer_Count <= 1))
    {
        WHT_I2C_BUS_Read_Write(bus, cache);
        return;
    }
    
    DMA_InitStruct.DMA_PeripheralBaseAddr = (unsigned int)&WHT_BUS->I2C_BUS->DR;//外设基地址
    if (WHT_BUS->Cache->Dir == I2C_Write)
    {
        DMA_InitStruct.DMA_MemoryBaseAddr = (unsigned int)WHT_BUS->Cache->Buffer;//数据源首地址
        DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST;                          //传输方向
        DMA_InitStruct.DMA_BufferSize = WHT_BUS->Cache->Buffer_Count;            //传输数据个数
        WHT_BUS->DMA_Send_Config.DMA_InitStruct = &DMA_InitStruct;

        while (WHT_BUS->DMA_Send_Config.Info->BSP_Mutex == SET);//等待没有外设使用此通道的DMA
        WHT_BUS->DMA_Send_Config.Info->BSP_Mutex = SET;         //DMA通道上锁
        WHT_DMA_BSP.WHT_Config(&WHT_BUS->DMA_Send_Config);      //配置当前DMA
    }
    else
    {
        DMA_InitStruct.DMA_MemoryBaseAddr = (unsigned int)WHT_BUS->Cache->Buffer;//数据源首地址
        DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;                          //传输方向
        DMA_InitStruct.DMA_BufferSize = WHT_BUS->Cache->Buffer_Count;            //传输数据个数
        WHT_BUS->DMA_Receive_Config.DMA_InitStruct = &DMA_InitStruct;

        while (WHT_BUS->DMA_Receive_Config.Info->BSP_Mutex == SET);//等待没有外设使用此通道的DMA
        WHT_BUS->DMA_Receive_Config.Info->BSP_Mutex = SET;         //DMA通道上锁
        WHT_DMA_BSP.WHT_Config(&WHT_BUS->DMA_Receive_Config);      //配置当前DMA
    }

    //检测总线状态
    wait_i2c_stop_send_over = WHT_BUS->Delay_Count;
    while (I2C_GetFlagStatus(WHT_BUS->I2C_BUS, I2C_FLAG_BUSY) == SET)
    {
        if (wait_i2c_stop_send_over-- == 0)
        {
            WHT_DMA_BSP.WHT_Close(WHT_BUS->Cache->Dir == I2C_Write ? &WHT_BUS->DMA_Send_Config : &WHT_BUS->DMA_Receive_Config);//关闭DMA
            *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_BUS_Error;
            *(WHT_I2C_BUS_Lock_enum*)&WHT_BUS->Info.Mutex = I2C_Unlock;
            return;
        }
    }

    WHT_I2C_BSP_Send_Start(bus);           //发送开始信号
    WHT_I2C_BSP_Send_Slave_Addr_Write(bus);//发送设备地址
    if (WHT_BUS->Info.State != I2C_No_Error)
        goto error;
    WHT_I2C_BSP_Send_Slave_Cmd(bus);       //发送命令
    if (WHT_BUS->Info.State != I2C_No_Error)
        goto error;
    
    if (WHT_BUS->Cache->Dir == I2C_Write)    //发送数据
    {
        WHT_BUS->Master_State_Code = I2C_Master_DMA_Send_End;//DMA Send End
        I2C_ITConfig(WHT_BUS->I2C_BUS, I2C_IT_ERR, ENABLE);//ON IT Error
        I2C_DMACmd(WHT_BUS->I2C_BUS, ENABLE);              //使能DMA请求
    }
    else                                      //接收数据
    {
        WHT_I2C_BSP_Send_Start(bus);          //Send i2c restart
        WHT_I2C_BSP_Send_Slave_Addr_Read(bus);//send read slave
        if (WHT_BUS->Info.State != I2C_No_Error)
            goto error;
        do
        {
            if (I2C_CheckEvent(WHT_BUS->I2C_BUS, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) == SUCCESS)//EV6 read addr have ack
                break;
            WHT_I2C_BSP_Check_Error_Code(bus);
            if (WHT_BUS->Info.State != I2C_No_Error)
                goto error;
        } while (1);
        I2C_AcknowledgeConfig(WHT_BUS->I2C_BUS, ENABLE);        //ON Send ACK
        WHT_BUS->Master_State_Code = I2C_Master_DMA_Receive_End;//DMA Receive End
        I2C_ITConfig(WHT_BUS->I2C_BUS, I2C_IT_ERR, ENABLE);     //ON IT Error
        I2C_DMACmd(WHT_BUS->I2C_BUS, ENABLE);                   //ON DMA请求
    }
    return;
error:
    I2C_GenerateSTOP(WHT_BUS->I2C_BUS, ENABLE);//send stop
    I2C_Cmd(WHT_BUS->I2C_BUS, DISABLE);        //关闭i2c
    WHT_DMA_BSP.WHT_Close(WHT_BUS->Cache->Dir == I2C_Write ? &WHT_BUS->DMA_Send_Config : &WHT_BUS->DMA_Receive_Config);
    *(WHT_I2C_BUS_Lock_enum*)&WHT_BUS->Info.Mutex = I2C_Unlock;
}
/*I2C功能使能控制*/
static void WHT_I2C_BSP_Receive_Cmd(WHT_I2C_BUS_t* bus, FunctionalState NewState)
{
    I2C_Cmd(WHT_BUS->I2C_BUS, NewState);
    I2C_AcknowledgeConfig(WHT_BUS->I2C_BUS, NewState);//ACK Send Enable
}


/*I2C总线配置*/
static void WHT_I2C_BUS_Config(WHT_I2C_BUS_t* bus)
{
    I2C_InitTypeDef I2C_InitStruct;

    WHT_BUS->Delay_Count = (unsigned int)(((float)(WHT_BUS->Info.Config.Sys_Rate_Hz))/((float)(WHT_BUS->Info.Config.I2C_Rate_Hz)));//延迟时间
    /*临时关闭I2C*/
    I2C_Cmd(WHT_BUS->I2C_BUS, DISABLE);
    /*I2C相关GPIO初始化*/
    WHT_BUS->GPIO.GPIO_Init_CB();

    I2C_InitStruct.I2C_Ack = I2C_Ack_Disable;                             //关闭ack应答响应
    I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//配置i2c的7位地址
    I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;                       //高电平比和低电平的比值，这里选择2：1倍
    I2C_InitStruct.I2C_ClockSpeed = WHT_BUS->Info.Config.I2C_Rate_Hz;     //配置波特率
    I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;                               //选择i2c工作模式
    I2C_InitStruct.I2C_OwnAddress1 = 0x32;                                //本机I2C的地址
    I2C_Init(WHT_BUS->I2C_BUS, &I2C_InitStruct);                          //开始初始化配置i2c

    if (1)//Master Mode
    {
		I2C_AcknowledgeConfig(WHT_BUS->I2C_BUS, DISABLE);                             //关闭ACK
        I2C_ITConfig(WHT_BUS->I2C_BUS, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, DISABLE);//关闭所有中断
    }
    else//从模式下不使用DMA
    {
        I2C_AcknowledgeConfig(WHT_BUS->I2C_BUS, ENABLE);                             //开启ACK
        I2C_ITConfig(WHT_BUS->I2C_BUS, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, ENABLE);//开启所有中断
        I2C_Cmd(WHT_BUS->I2C_BUS, ENABLE);//使能iic
    }
}
/*I2C中断优先级配置*/
static void WHT_I2C_BUS_NVIC_Configuration(WHT_I2C_BUS_t* bus)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    /* 嵌套向量中断控制器组选择 */
    //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

    /* 配置中断源 */
    if (strcmp(WHT_BUS->Info.Name, WHT_I2C1_Name) == 0)
        NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
    else if (strcmp(WHT_BUS->Info.Name, WHT_I2C2_Name) == 0)
        NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQn;
    else
        return;
    /* 抢断优先级*/
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = WHT_BUS->Info.Config.IT_PreemptionPriority;
    /* 子优先级 */
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = WHT_BUS->Info.Config.IT_SubPriority;
    /* 使能中断 */
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    /* 初始化配置NVIC */
    NVIC_Init(&NVIC_InitStructure);

    /* 配置中断源 */
    if (strcmp(WHT_BUS->Info.Name, WHT_I2C1_Name) == 0)
        NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;
    else if (strcmp(WHT_BUS->Info.Name, WHT_I2C2_Name) == 0)
        NVIC_InitStructure.NVIC_IRQChannel = I2C2_ER_IRQn;
    else
        return;
    /* 抢断优先级*/
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = WHT_BUS->Info.Config.IT_PreemptionPriority;
    /* 子优先级 */
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = WHT_BUS->Info.Config.IT_SubPriority;
    /* 使能中断 */
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    /* 初始化配置NVIC */
    NVIC_Init(&NVIC_InitStructure);
}
/*总线初始化*/
static void WHT_I2C_BUS_Init(WHT_I2C_BUS_t* bus)
{
    if (strcmp(WHT_BUS->Info.Name, WHT_I2C1_Name) == 0)
    {
        WHT_BUS->I2C_BUS = I2C1;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
        WHT_I2C_BUS[0] = (WHT_I2C_BUS_Private_t*)bus;
    }
    else if (strcmp(WHT_BUS->Info.Name, WHT_I2C2_Name) == 0)
    {
        WHT_BUS->I2C_BUS = I2C2;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
        WHT_I2C_BUS[1] = (WHT_I2C_BUS_Private_t*)bus;
    }
    else
        return;

    *(WHT_I2C_BUS_Lock_enum*)&WHT_BUS->Info.Mutex = I2C_Unlock;
    *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_No_Error;    
    WHT_BUS->Cache = NULL;
    WHT_BUS->DMA_Send_Config.IT_Callback = NULL;
    WHT_BUS->DMA_Receive_Config.IT_Callback = NULL;
    WHT_BUS->Master_State_Code = I2C_Master_Start;

    if (1)//这里是I2C Master Mode
    {
        if (strcmp(WHT_BUS->Info.Name, WHT_I2C1_Name) == 0)
        {
            WHT_BUS->DMA_Send_Config.Name = Source_I2C1_TX;
            WHT_BUS->DMA_Send_Config.IT_Callback = WHT_I2C1_BSP_DMA_Send_Receive_Callback;
            WHT_BUS->DMA_Receive_Config.Name = Source_I2C1_RX;
            WHT_BUS->DMA_Receive_Config.IT_Callback = WHT_I2C1_BSP_DMA_Send_Receive_Callback;
        }
        else if (strcmp(WHT_BUS->Info.Name, WHT_I2C2_Name) == 0)
        {
            WHT_BUS->DMA_Send_Config.Name = Source_I2C2_TX;
            WHT_BUS->DMA_Send_Config.IT_Callback = WHT_I2C2_BSP_DMA_Send_Receive_Callback;
            WHT_BUS->DMA_Receive_Config.Name = Source_I2C2_RX;
            WHT_BUS->DMA_Receive_Config.IT_Callback = WHT_I2C2_BSP_DMA_Send_Receive_Callback;
        }
        WHT_DMA_BSP.WHT_Register(&WHT_BUS->DMA_Send_Config);
        WHT_DMA_BSP.WHT_Register(&WHT_BUS->DMA_Receive_Config);
        I2C_DMALastTransferCmd(WHT_BUS->I2C_BUS, ENABLE);
    }
    //从模式下不使用DMA
    WHT_I2C_BUS_NVIC_Configuration(bus);
    WHT_I2C_BUS_Config(bus);
}

/*总线速率设置*/
static void WHT_I2C_BUS_Set_Rate(WHT_I2C_BUS_t* bus)
{
    WHT_I2C_BUS_Config(bus);
}
/*总线从设备个数*/
static char WHT_I2C_BUS_Scan_Mount_Count(WHT_I2C_BUS_t* bus)
{
    unsigned int wait_i2c_stop_send_over;/*当发送stop后关闭i2c则不会立即关闭i2c的此时在向外发送stop信号*/
    char i2c_slave_count = 0;
    WHT_I2C_Cache_t cache = {0};

    *(WHT_I2C_BUS_Lock_enum*)&WHT_BUS->Info.Mutex = I2C_Lock;
    *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_No_Error;
    WHT_BUS->Cache = &cache;
    I2C_ITConfig(WHT_BUS->I2C_BUS, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, DISABLE);
    //检测总线状态
    wait_i2c_stop_send_over = WHT_BUS->Delay_Count;
    do
    {
        if (I2C_GetFlagStatus(WHT_BUS->I2C_BUS, I2C_FLAG_BUSY) != RESET)
        {
            if (wait_i2c_stop_send_over-- == 0)
            {
                *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_BUS_Error;
                *(WHT_I2C_BUS_Lock_enum*)&WHT_BUS->Info.Mutex = I2C_Unlock;
                return i2c_slave_count;
            }
        }
        else
            break;
    } while (1);
    do
    {
        WHT_I2C_BSP_Send_Start(bus);           //发送开始信号
        WHT_I2C_BSP_Send_Slave_Addr_Write(bus);//发送设备地址
        if (WHT_BUS->Info.State != I2C_No_Error)
            break;
        WHT_I2C_BSP_Send_Slave_Cmd(bus);       //发送命令
        I2C_GenerateSTOP(WHT_BUS->I2C_BUS, ENABLE);//发送结束信号
        I2C_Cmd(WHT_BUS->I2C_BUS, DISABLE);//关闭i2c
        if (WHT_BUS->Info.State == I2C_No_Error)
            i2c_slave_count++;
        else if (WHT_BUS->Info.State == I2C_Slave_No_ACK)
            *(WHT_I2C_BUS_State_enum*)&WHT_BUS->Info.State = I2C_No_Error;
        else
            break;
        if (WHT_BUS->Cache->Addr_7Bit++ == (0xff >> 1))
            break;
    } while (1);
    *(WHT_I2C_BUS_Lock_enum*)&WHT_BUS->Info.Mutex = I2C_Unlock;
    return i2c_slave_count;
}
/*注册软件I2C总线*/
static WHT_I2C_BUS_t* WHT_I2C_BUS_Register(char* name, WHT_I2C_BUS_Config_t* config, void (*gpio_init_callback)(void))
{
    char Pos;

    if (((strcmp(name, WHT_I2C1_Name) == 0)) && (WHT_I2C_BUS[0] == NULL))
        Pos = 0;
    else if (((strcmp(name, WHT_I2C2_Name) == 0)) && (WHT_I2C_BUS[1] == NULL))
        Pos = 1;
    else
        return NULL;

    WHT_I2C_BUS[Pos] = malloc(sizeof(WHT_I2C_BUS_Private_t));
    if (WHT_I2C_BUS[Pos])
    {
        WHT_I2C_BUS[Pos]->Info.Name = name;
        WHT_I2C_BUS[Pos]->GPIO.GPIO_Init_CB = gpio_init_callback;
        memcpy(&WHT_I2C_BUS[Pos]->Info.Config, config, sizeof(WHT_I2C_BUS_Config_t));
        WHT_I2C_BUS_Init((WHT_I2C_BUS_t*)WHT_I2C_BUS[Pos]);
        return (WHT_I2C_BUS_t*)WHT_I2C_BUS[Pos];
    }
    return NULL;
}
/*注销软件I2C总线*/
static void WHT_I2C_BUS_Unregister(WHT_I2C_BUS_t* bus)
{
    if (WHT_I2C_BUS[0] == WHT_BUS)
        WHT_I2C_BUS[0] = NULL;
    else if (WHT_I2C_BUS[1] == WHT_BUS)
        WHT_I2C_BUS[1] = NULL;
    else
        return;
    free(WHT_BUS);
}

/*全局常量*/
const WHT_I2C_BUS_OPS_t WHT_I2C_BUS_OPS =
{
    .Register         = WHT_I2C_BUS_Register,
    .Unregister       = WHT_I2C_BUS_Unregister,
    .Set_Rate         = WHT_I2C_BUS_Set_Rate,
    .Scan_Mount_Count = WHT_I2C_BUS_Scan_Mount_Count,
    .Receive_EN       = WHT_I2C_BSP_Receive_Cmd,
    .Read_Write       = WHT_I2C_BUS_Read_Write,
    .Read_Write_IT    = WHT_I2C_BUS_Read_Write_IT,
    .Read_Write_DMA   = WHT_I2C_BUS_Read_Write_DMA,
};




/*I2C事件回调函数*/
static void WHT_I2C_BSP_EV_IRQHandler(WHT_I2C_BUS_Private_t* BUS, unsigned int* Count)
{    
    I2C_GetLastEvent(BUS->I2C_BUS);
    switch (BUS->Master_State_Code)
    {
    case I2C_Master_Start:
        I2C_Send7bitAddress(BUS->I2C_BUS, BUS->Cache->Addr_7Bit << 1, I2C_Write);
        BUS->Master_State_Code = I2C_Master_Write_Addr;
        *Count = 0;
        break;
    case I2C_Master_Restart:
        I2C_Send7bitAddress(BUS->I2C_BUS, BUS->Cache->Addr_7Bit << 1, I2C_Read);
        BUS->Master_State_Code = I2C_Master_Read_Addr;
        *Count = 0;
        break;
    case I2C_Master_Write_Addr:
        if (BUS->Cache->Cmd_Count < 1)
        {
            I2C_GenerateSTOP(BUS->I2C_BUS, ENABLE);//send stop
            I2C_Cmd(BUS->I2C_BUS, DISABLE);
            WHT_I2C_BSP_User_IT_Callback(BUS);
            break;
        }
        else
            BUS->Master_State_Code = I2C_Master_Send_Cmd;
        //not add break
    case I2C_Master_Send_Cmd:
        if (*Count == BUS->Cache->Cmd_Count)//cmd 发送完
        {
            *Count = 0;
            if (BUS->Cache->Dir == I2C_Write)//是否发送数据
            {
                BUS->Master_State_Code = I2C_Master_Send_Data;
            }
            else//读取数据
            {
                if (BUS->Cache->Buffer_Count > 0)
                {
                    I2C_ReceiveData(BUS->I2C_BUS);          //clear BTF
                    I2C_GenerateSTART(BUS->I2C_BUS, ENABLE);//Send i2c Start
                    BUS->Master_State_Code = I2C_Master_Restart;
                }
                else
                {
                    I2C_GenerateSTOP(BUS->I2C_BUS, ENABLE);//send stop
                    I2C_Cmd(BUS->I2C_BUS, DISABLE);
                    I2C_ITConfig(BUS->I2C_BUS, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, DISABLE);//off all interrupt
                    WHT_I2C_BSP_User_IT_Callback(BUS);
                }
                break;
            }
        }
        else
        {
            I2C_SendData(BUS->I2C_BUS, BUS->Cache->Cmd[(*Count)++]);
            break;
        }
    case I2C_Master_Send_Data:
        if (*Count < BUS->Cache->Buffer_Count)
        {
            I2C_SendData(BUS->I2C_BUS, BUS->Cache->Buffer[(*Count)++]);
            if (*Count == BUS->Cache->Buffer_Count)
            {
                I2C_ITConfig(BUS->I2C_BUS, I2C_IT_BUF, DISABLE);//off TxE interrupt
            }
        }
        else
        {
            I2C_GenerateSTOP(BUS->I2C_BUS, ENABLE);//send stop
            I2C_Cmd(BUS->I2C_BUS, DISABLE);
            I2C_ITConfig(BUS->I2C_BUS, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, DISABLE);//off all interrupt
            WHT_I2C_BSP_User_IT_Callback(BUS);
        }
        break;
    case I2C_Master_Read_Addr:
        if (BUS->Cache->Buffer_Count == 1)
        {
            I2C_GenerateSTOP(BUS->I2C_BUS, ENABLE);
        }
        else
            I2C_AcknowledgeConfig(BUS->I2C_BUS, ENABLE);
        I2C_ITConfig(BUS->I2C_BUS, I2C_IT_BUF, ENABLE);//on rx interrupt
        BUS->Master_State_Code = I2C_Master_Receive_Data;
        break;
    case I2C_Master_Receive_Data:
        BUS->Cache->Buffer[(*Count)++] = I2C_ReceiveData(BUS->I2C_BUS);
        if ((*Count + 1) == BUS->Cache->Buffer_Count)//倒数第2个数据接收完成
        {
            I2C_AcknowledgeConfig(BUS->I2C_BUS, DISABLE);
            I2C_GenerateSTOP(BUS->I2C_BUS, ENABLE);
        }
        if (*Count >= BUS->Cache->Buffer_Count)
        {
            I2C_Cmd(BUS->I2C_BUS, DISABLE);
            I2C_ITConfig(BUS->I2C_BUS, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, DISABLE);//off all interrupt
            WHT_I2C_BSP_User_IT_Callback(BUS);
        }
        break;
    case I2C_Master_DMA_Send_End:
        I2C_GenerateSTOP(BUS->I2C_BUS, ENABLE);//send stop
        I2C_Cmd(BUS->I2C_BUS, DISABLE);
        I2C_ITConfig(BUS->I2C_BUS, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, DISABLE);//OFF All Interrupt
        BUS->Master_State_Code = I2C_Master_Start;
        WHT_I2C_BSP_User_IT_Callback(BUS);
        break;
    }
}
/*I2C错误回调函数*/
static void WHT_I2C_BSP_ER_IRQHandler(WHT_I2C_BUS_Private_t* BUS)
{
#if 0
    unsigned int Error_Code;

    Error_Code = I2C_ReadRegister(BUS->I2C_BUS, I2C_Register_SR1);
    Error_Code &= I2C_FLAG_AF | I2C_FLAG_BERR | I2C_FLAG_TIMEOUT | I2C_FLAG_PECERR | I2C_FLAG_OVR | I2C_FLAG_ARLO;
    if (Error_Code & I2C_FLAG_AF)
        *(WHT_I2C_BUS_State_enum*)&BUS->Info.State = I2C_Slave_No_ACK;
    else if (Error_Code & I2C_FLAG_BERR)
        *(WHT_I2C_BUS_State_enum*)&BUS->Info.State = I2C_BUS_Error;
    else if (Error_Code & I2C_FLAG_TIMEOUT)
        *(WHT_I2C_BUS_State_enum*)&BUS->Info.State = I2C_Tx_Send_Error;
    else if (Error_Code & I2C_FLAG_PECERR)
        *(WHT_I2C_BUS_State_enum*)&BUS->Info.State = I2C_Other_Error;
    else if (Error_Code & I2C_FLAG_OVR)
        *(WHT_I2C_BUS_State_enum*)&BUS->Info.State = I2C_Rx_Over_Error;
    else if (Error_Code & I2C_FLAG_ARLO)
        *(WHT_I2C_BUS_State_enum*)&BUS->Info.State = I2C_ARLO_Error;
#else//速度慢
    if (I2C_GetITStatus(BUS->I2C_BUS, I2C_IT_BERR) == SET)
    {
        *(WHT_I2C_BUS_State_enum*)&BUS->Info.State = I2C_BUS_Error;
    }
    else if (I2C_GetITStatus(BUS->I2C_BUS, I2C_IT_AF) == SET)
    {
        *(WHT_I2C_BUS_State_enum*)&BUS->Info.State = I2C_Slave_No_ACK;
    }
    else if (I2C_GetITStatus(BUS->I2C_BUS, I2C_IT_ARLO) == SET)
    {
        *(WHT_I2C_BUS_State_enum*)&BUS->Info.State = I2C_ARLO_Error;
    }
    else if (I2C_GetITStatus(BUS->I2C_BUS, I2C_IT_OVR) == SET)
    {
        if (BUS->Cache->Dir == I2C_Write)
        {
            *(WHT_I2C_BUS_State_enum*)&BUS->Info.State = I2C_Tx_Send_Error;
        }
        else
        {
            *(WHT_I2C_BUS_State_enum*)&BUS->Info.State = I2C_Rx_Over_Error;
        }
    }
#endif

    I2C_DMACmd(BUS->I2C_BUS, DISABLE); //Off DMA请求
    if (BUS->Master_State_Code == I2C_Master_DMA_Receive_End)
    {
        WHT_DMA_BSP.WHT_Close(&BUS->DMA_Receive_Config);
    }
    else if (BUS->Master_State_Code == I2C_Master_DMA_Send_End)
    {
        WHT_DMA_BSP.WHT_Close(&BUS->DMA_Send_Config);
    }

    I2C_GenerateSTOP(BUS->I2C_BUS, ENABLE);
    I2C_ITConfig(BUS->I2C_BUS, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, DISABLE);//Off All Interrupt
    I2C_AcknowledgeConfig(BUS->I2C_BUS, DISABLE);
    I2C_Cmd(BUS->I2C_BUS, DISABLE);                                           //Off i2c
    I2C_ClearITPendingBit(BUS->I2C_BUS, I2C_IT_AF | I2C_IT_BERR | I2C_IT_ARLO | I2C_IT_OVR | I2C_IT_PECERR | I2C_IT_TIMEOUT);
    BUS->Master_State_Code = I2C_Master_Start;
    WHT_I2C_BSP_User_IT_Callback(BUS);
}


/*I2C1 正常事件中断服务程序*/
void I2C1_EV_IRQHandler(void)
{
    static unsigned int Count;

    WHT_I2C_BSP_EV_IRQHandler(WHT_I2C_BUS[0], &Count);
}
/*I2C1 错误事件中断服务程序*/
void I2C1_ER_IRQHandler(void)
{
    WHT_I2C_BSP_ER_IRQHandler(WHT_I2C_BUS[0]);
}


/*I2C2 正常事件中断服务程序*/
void I2C2_EV_IRQHandler(void)
{
    static unsigned int Count;

    WHT_I2C_BSP_EV_IRQHandler(WHT_I2C_BUS[1], &Count);
}
/*I2C2 错误事件中断服务程序*/
void I2C2_ER_IRQHandler(void)
{
    WHT_I2C_BSP_ER_IRQHandler(WHT_I2C_BUS[1]);
}
